package correctionPackage;

import java.util.Vector;

import neuronsPackage.Arc;
import neuronsPackage.Couche;
import neuronsPackage.Neuronne;
import reseauPackage.Perceptron;

public class Correcteur 
{
	private double mu ;
	private Perceptron percept ;

	public Correcteur(Perceptron percept)
	{
		this.mu = 0.2 ;
		this.percept = percept ;
	}

	public void corriger(Vector<Double> valeursAttendues)
	{
		
			Couche coucheSortie = percept.getCoucheSortie() ;
			// correction sur la couche de sortie
			for(int i = 0 ; i<coucheSortie.getListeNeuronnes().size() ; i++ )
			{
				Neuronne n = coucheSortie.getNeuronne(i);
				
				// delta i = f'(xi) * ( ai - ai* )
				// deltai = f(x) ( 1 - f(x) ) ( a - a*) 
				
				
				double somme = n.calculerSommeEntrees();
				double deriv = n.getFonctionActivation().deriv( somme )  ;
				
				double sigsortie =  n.getSignalDeSortie() ;
				double attendu = valeursAttendues.get(i) ; 
				double diff = ( sigsortie -  attendu  ) ;
				
				double deltai = deriv * diff ; 
				
				for(int l = 0 ; l < n.getLiensEntrants().size() ; l++)
				{
					Arc arc = n.getLiensEntrants().get(l);
					
					double ancienPoid = arc.getPoids() ;
					
					double nouveauPoid = ancienPoid -  mu * deltai *  arc.getNeuronneDepart().getSignalDeSortie() ;
					
					arc.setPoids(nouveauPoid);
					
					//System.out.print("ancien poids = "+ancienPoid);
					//System.out.println(" nouveau poids = "+nouveauPoid);
				}
			}
			
			if( percept.getCoucheCachee() != null )
			{
				Couche coucheCachee = percept.getCoucheCachee() ;
				
				// correction sur la couche cachee
				for(int i = 0 ; i<coucheCachee.getListeNeuronnes().size() ; i++ )
				{
					Neuronne n = coucheCachee.getNeuronne(i);
					
					
					
					double sommePoidsDelta = 0.0 ;
					int cp =-1;
					for(Arc arc : n.getLiensSortants())
					{
						cp++;
						sommePoidsDelta = sommePoidsDelta + ( arc.getPoids() * ( valeursAttendues.get(cp) - arc.getNeuronneArrivee().getSignalDeSortie()) );
					}
					
					
					double deltaj = n.getFonctionActivation().deriv( n.calculerSommeEntrees() ) * sommePoidsDelta ;
					
					for(int l = 0 ; l < n.getLiensEntrants().size() ; l++)
					{
						Arc arc = n.getLiensEntrants().get(l);
						
						double ancienPoid = arc.getPoids() ;
						
						double nouveauPoid = ancienPoid -  mu * deltaj *  arc.getNeuronneDepart().getSignalDeSortie() ;
						
						arc.setPoids(nouveauPoid);
					}
				}
				
			}

	}
}
